home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2004 April / Gamestar_61_2004-04_dvdb.iso / DVDStar / Editace / hltp.exe / {app} / Source Code / Zoners Half-Life Tools / common / scriplib.cpp < prev    next >
C/C++ Source or Header  |  2002-06-13  |  10KB  |  363 lines

  1. #include "cmdlib.h"
  2. #include "filelib.h"
  3. #include "messages.h"
  4. #include "log.h"
  5. #include "scriplib.h"
  6.  
  7. char            g_token[MAXTOKEN];
  8. char            g_TXcommand;
  9.  
  10. typedef struct
  11. {
  12.     char            filename[_MAX_PATH];
  13.     char*           buffer;
  14.     char*           script_p;
  15.     char*           end_p;
  16.     int             line;
  17. }
  18. script_t;
  19.  
  20.  
  21. #define    MAX_INCLUDES    8
  22.  
  23.  
  24. static script_t s_scriptstack[MAX_INCLUDES];
  25. script_t*       s_script;
  26. int             s_scriptline;
  27. bool            s_endofscript;
  28. bool            s_tokenready;                                // only true if UnGetToken was just called
  29.  
  30.  
  31. //  AddScriptToStack
  32. //  LoadScriptFile
  33. //  ParseFromMemory
  34. //  UnGetToken
  35. //  EndOfScript
  36. //  GetToken
  37. //  TokenAvailable
  38.  
  39. // =====================================================================================
  40. //  AddScriptToStack
  41. // =====================================================================================
  42. static void     AddScriptToStack(const char* const filename)
  43. {
  44.     int             size;
  45.  
  46.     s_script++;
  47.  
  48.     if (s_script == &s_scriptstack[MAX_INCLUDES])
  49.         Error("s_script file exceeded MAX_INCLUDES");
  50.  
  51.     strcpy(s_script->filename, filename);
  52.  
  53.     size = LoadFile(s_script->filename, (char**)&s_script->buffer);
  54.  
  55.     Log("Entering %s\n", s_script->filename);
  56.  
  57.     s_script->line = 1;
  58.     s_script->script_p = s_script->buffer;
  59.     s_script->end_p = s_script->buffer + size;
  60. }
  61.  
  62. // =====================================================================================
  63. //  LoadScriptFile
  64. // =====================================================================================
  65. void            LoadScriptFile(const char* const filename)
  66. {
  67.     s_script = s_scriptstack;
  68.     AddScriptToStack(filename);
  69.  
  70.     s_endofscript = false;
  71.     s_tokenready = false;
  72. }
  73.  
  74. // =====================================================================================
  75. //  ParseFromMemory
  76. // =====================================================================================
  77. void            ParseFromMemory(char* buffer, const int size)
  78. {
  79.     s_script = s_scriptstack;
  80.     s_script++;
  81.  
  82.     if (s_script == &s_scriptstack[MAX_INCLUDES])
  83.         Error("s_script file exceeded MAX_INCLUDES");
  84.  
  85.     strcpy(s_script->filename, "memory buffer");
  86.  
  87.     s_script->buffer = buffer;
  88.     s_script->line = 1;
  89.     s_script->script_p = s_script->buffer;
  90.     s_script->end_p = s_script->buffer + size;
  91.  
  92.     s_endofscript = false;
  93.     s_tokenready = false;
  94. }
  95.  
  96. // =====================================================================================
  97. //  UnGetToken
  98. /*
  99.  * Signals that the current g_token was not used, and should be reported
  100.  * for the next GetToken.  Note that
  101.  * 
  102.  * GetToken (true);
  103.  * UnGetToken ();
  104.  * GetToken (false);
  105.  * 
  106.  * could cross a line boundary.
  107.  */
  108. // =====================================================================================
  109. void            UnGetToken()
  110. {
  111.     s_tokenready = true;
  112. }
  113.  
  114. // =====================================================================================
  115. //  EndOfScript
  116. // =====================================================================================
  117. bool            EndOfScript(const bool crossline)
  118. {
  119.     if (!crossline)
  120.         Error("Line %i is incomplete (did you place a \" inside an entity string?) \n", s_scriptline);
  121.  
  122.     if (!strcmp(s_script->filename, "memory buffer"))
  123.     {
  124.         s_endofscript = true;
  125.         return false;
  126.     }
  127.  
  128.     free(s_script->buffer);
  129.  
  130.     if (s_script == s_scriptstack + 1)
  131.     {
  132.         s_endofscript = true;
  133.         return false;
  134.     }
  135.  
  136.     s_script--;
  137.     s_scriptline = s_script->line;
  138.  
  139.     Log("returning to %s\n", s_script->filename);
  140.  
  141.     return GetToken(crossline);
  142. }
  143.  
  144. // =====================================================================================
  145. //  GetToken
  146. // =====================================================================================
  147. bool            GetToken(const bool crossline)
  148. {
  149.     char           *token_p;
  150.  
  151.     if (s_tokenready)                                        // is a g_token allready waiting?
  152.     {
  153.         s_tokenready = false;
  154.         return true;
  155.     }
  156.  
  157.     if (s_script->script_p >= s_script->end_p)
  158.         return EndOfScript(crossline);
  159.  
  160.     // skip space
  161. skipspace:
  162.     while (*s_script->script_p <= 32)
  163.     {
  164.         if (s_script->script_p >= s_script->end_p)
  165.             return EndOfScript(crossline);
  166.  
  167.         if (*s_script->script_p++ == '\n')
  168.         {
  169.             if (!crossline)
  170.                 Error("Line %i is incomplete (did you place a \" inside an entity string?) \n", s_scriptline);
  171.             s_scriptline = s_script->line++;
  172.         }
  173.     }
  174.  
  175.     if (s_script->script_p >= s_script->end_p)
  176.         return EndOfScript(crossline);
  177.  
  178.     // comment fields
  179.     if (*s_script->script_p == ';' || *s_script->script_p == '#' || // semicolon and # is comment field
  180.         (*s_script->script_p == '/' && *((s_script->script_p) + 1) == '/')) // also make // a comment field
  181.     {
  182.         if (!crossline)
  183.             Error("Line %i is incomplete (did you place a \" inside an entity string?) \n", s_scriptline);
  184.  
  185.         //ets+++
  186.         if (*s_script->script_p == '/')
  187.             s_script->script_p++;
  188.         if (s_script->script_p[1] == 'T' && s_script->script_p[2] == 'X')
  189.             g_TXcommand = s_script->script_p[3];             // AR: "//TX#"-style comment
  190.  
  191.         //ets---
  192.         while (*s_script->script_p++ != '\n')
  193.         {
  194.             if (s_script->script_p >= s_script->end_p)
  195.                 return EndOfScript(crossline);
  196.         }
  197.         //ets+++
  198.         s_scriptline = s_script->line++;                       // AR: this line was missing
  199.         //ets---
  200.         goto skipspace;
  201.     }
  202.  
  203.     // copy g_token
  204.     token_p = g_token;
  205.  
  206.     if (*s_script->script_p == '"')
  207.     {
  208.         // quoted token
  209.         s_script->script_p++;
  210.         while (*s_script->script_p != '"')
  211.         {
  212.             *token_p++ = *s_script->script_p++;
  213.  
  214.             if (s_script->script_p == s_script->end_p)
  215.                 break;
  216.  
  217.             if (token_p == &g_token[MAXTOKEN])
  218.                 Error("Token too large on line %i\n", s_scriptline);
  219.         }
  220.         s_script->script_p++;
  221.     }
  222.     else
  223.     {
  224.         // regular token
  225.         while (*s_script->script_p > 32 && *s_script->script_p != ';')
  226.         {
  227.             *token_p++ = *s_script->script_p++;
  228.  
  229.             if (s_script->script_p == s_script->end_p)
  230.                 break;
  231.  
  232.             if (token_p == &g_token[MAXTOKEN])
  233.                 Error("Token too large on line %i\n", s_scriptline);
  234.         }
  235.     }
  236.  
  237.     *token_p = 0;
  238.  
  239.     if (!strcmp(g_token, "$include"))
  240.     {
  241.         GetToken(false);
  242.         AddScriptToStack(g_token);
  243.         return GetToken(crossline);
  244.     }
  245.  
  246.     return true;
  247. }
  248.  
  249. #if 0
  250. // AJM: THIS IS REDUNDANT
  251. // =====================================================================================
  252. //  ParseWadToken
  253. //      basically the same as gettoken, except it isnt limited by MAXTOKEN and is
  254. //      specificaly designed to parse out the wadpaths from the wad keyvalue and dump
  255. //      them into the wadpaths list
  256. //      this was implemented as a hack workaround for Token Too Large errors caused by
  257. //      having long wadpaths or lots of wads in the map editor.
  258. extern void        PushWadPath(const char* const path, bool inuse);
  259. // =====================================================================================
  260. void            ParseWadToken(const bool crossline)
  261. {
  262.     // code somewhat copied from GetToken()
  263.     int             i, j;
  264.     char*           token_p;
  265.     char            temp[_MAX_PATH];
  266.  
  267.     if (s_script->script_p >= s_script->end_p)
  268.         return;
  269.  
  270.     // skip space
  271.     while (*s_script->script_p <= 32)
  272.     {
  273.         if (s_script->script_p >= s_script->end_p)
  274.             return;
  275.  
  276.         if (*s_script->script_p++ == '\n')
  277.         {
  278.             if (!crossline)
  279.                 Error("Line %i is incomplete (did you place a \" inside an entity string?) \n", s_scriptline);
  280.             s_scriptline = s_script->line++;
  281.         }
  282.     }
  283.  
  284.     // EXPECT A QUOTE
  285.     if (*s_script->script_p++ != '"')
  286.         Error("Line %i: Expected a wadpaths definition, got '%s'\n", s_scriptline, *--s_script->script_p);
  287.  
  288.     // load wadpaths manually
  289.     bool    endoftoken = false;
  290.     for (i = 0; !endoftoken; i++)
  291.     {
  292.         // get the path
  293.         for (j = 0; ; j++)
  294.         {
  295.             token_p = ++s_script->script_p;
  296.             
  297.             // assert max path length
  298.             if (j > _MAX_PATH)
  299.                 Error("Line %i: Wadpath definition %i is too long (%s)\n", s_scriptline, temp);
  300.  
  301.             if (*token_p == '\n')
  302.                 Error("Line %i: Expected a wadpaths definition, got linebreak\n", s_scriptline);
  303.  
  304.             if (*token_p == '"')            // end of wadpath definition
  305.             {
  306.                 if (i == 0 && j == 0)       // no wadpaths!
  307.                 {
  308.                     Warning("No wadpaths specified.\n");
  309.                     return;
  310.                 }
  311.  
  312.                 endoftoken = true;
  313.                 break;
  314.             }
  315.  
  316.             if (*token_p == ';')            // end of this wadpath
  317.                 break;
  318.  
  319.             temp[j] = *token_p;
  320.             temp[j + 1] = 0;
  321.         }
  322.  
  323.         // push it into the list
  324.         PushWadPath(temp, true);
  325.         temp[0] = 0;
  326.     }
  327.  
  328.     for (; *s_script->script_p != '\n'; s_script->script_p++)
  329.     {
  330.     }
  331. }
  332. #endif
  333.  
  334. // =====================================================================================
  335. //  TokenAvailable
  336. //      returns true if there is another token on the line
  337. // =====================================================================================
  338. bool            TokenAvailable()
  339. {
  340.     char           *search_p;
  341.  
  342.     search_p = s_script->script_p;
  343.  
  344.     if (search_p >= s_script->end_p)
  345.         return false;
  346.  
  347.     while (*search_p <= 32)
  348.     {
  349.         if (*search_p == '\n')
  350.             return false;
  351.  
  352.         search_p++;
  353.  
  354.         if (search_p == s_script->end_p)
  355.             return false;
  356.     }
  357.  
  358.     if (*search_p == ';')
  359.         return false;
  360.  
  361.     return true;
  362. }
  363.